{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# Getting started with Cirq and Quantinuum on Azure Quantum\n",
    "\n",
    "This notebook shows how to send a basic quantum circuit expressed using the [Cirq library](https://quantumai.google/cirq) to a Quantinuum target via the Azure Quantum service."
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "First, install `azure-quantum` with the Cirq dependencies."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "source": [
    "# To install the Azure Quantum client package with support for\n",
    "# Cirq, uncomment and run the line below:\n",
    "#\n",
    "# !pip install azure-quantum[cirq]==0.19.2109.165653 --quiet"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Connecting to the Azure Quantum service\n",
    "\n",
    "To connect to the Azure Quantum service, find the resource ID and location of your Workspace from the Azure portal here: https://portal.azure.com. Navigate to your Azure Quantum workspace and copy the values from the header.\n",
    "\n",
    "<img src=\"../azure-quantum-resource-id.png\" alt=\"How to retrieve the resource ID and location from an Azure Quantum workspace\">"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "source": [
    "from azure.quantum.cirq import AzureQuantumService\n",
    "service = AzureQuantumService(\n",
    "    resource_id=\"\",\n",
    "    location=\"\",\n",
    "    default_target=\"quantinuum.sim.h1-1sc\"\n",
    ")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### List all targets\n",
    "\n",
    "You can now list all the targets that you have access to, including the current queue time and availability. Running this method will trigger authentication to your Microsoft account, if you're not already logged in."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "source": [
    "service.targets()"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "[<Target name=\"ionq.qpu\", avg. queue time=250 s, Available>,\n",
       " <Target name=\"ionq.simulator\", avg. queue time=0 s, Available>,\n",
       " <Target name=\"quantinuum.qpu.h1-1\", avg. queue time=0 s, Unavailable>,\n",
       " <Target name=\"quantinuum.sim.h1-1sc\", avg. queue time=0 s, Available>,\n",
       " <Target name=\"quantinuum.sim.h1-1e\", avg. queue time=26 s, Available>]"
      ]
     },
     "metadata": {},
     "execution_count": 3
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Run a simple circuit\n",
    "\n",
    "Now, let's create a simple Cirq circuit to run.\n",
    "\n",
    "This notebook assumes some familiarity with Cirq. To read more about Cirq, review the [Cirq documentation](https://quantumai.google/cirq)."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "source": [
    "import cirq\n",
    "\n",
    "q0, q1 = cirq.LineQubit.range(2)\n",
    "circuit = cirq.Circuit(\n",
    "    cirq.H(q0), # Hadamard\n",
    "    cirq.CNOT(q0, q1), # CNOT\n",
    "    cirq.measure(q0, q1, key='b') # Measure both qubits\n",
    ")\n",
    "circuit"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "0: ───H───@───M('b')───\n",
       "          │   │\n",
       "1: ───────X───M────────"
      ],
      "text/html": [
       "<pre style=\"overflow: auto; white-space: pre;\">0: ───H───@───M(&#x27;b&#x27;)───\n",
       "          │   │\n",
       "1: ───────X───M────────</pre>"
      ]
     },
     "metadata": {},
     "execution_count": 4
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "You can now run the program via the Azure Quantum service and get the result. The following cell will submit a job that runs the circuit with 100 shots, wait until the job is completed and return the results."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "source": [
    "result = service.run(program=circuit, repetitions=100)"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "......."
     ]
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "This returns a `cirq.Result` object. Note that we used the API validator provided by Quantinuum, which only returns zeros."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "source": [
    "print(result)"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "b=0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n"
     ]
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Asynchronous workflow using Jobs\n",
    "\n",
    "For long-running circuits, it can be useful to run them asynchronously. The `service.create_job` method returns a `Job`, which you can use to get the results after the job has run successfully."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "source": [
    "job = service.create_job(\n",
    "    program=circuit,\n",
    "    repetitions=100\n",
    ")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "To check on the job status, use `job.status()`:"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "source": [
    "job.status()"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "'Waiting'"
      ]
     },
     "metadata": {},
     "execution_count": 8
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "To wait for the job to be done and get the results, use the blocking call `job.results()`:"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "source": [
    "result = job.results()\n",
    "print(result)"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      ".......{'m_b': ['00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00']}\n"
     ]
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "Note that this does not return a `cirq.Result` object. Instead it returns a dictionary that is specific to the Quantinuum simulator."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "source": [
    "type(result)"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "dict"
      ]
     },
     "metadata": {},
     "execution_count": 10
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "source": [
    "# Print package versions used in this notebook\n",
    "import cirq\n",
    "print('\\n'.join(f'{m.__name__}=={m.__version__}' for m in globals().values() if getattr(m, '__version__', None)))"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "cirq==0.12.0\n"
     ]
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [],
   "outputs": [],
   "metadata": {}
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}